package com.wang;

import java.sql.*;

/**
 * 事务学习
 * 1.事务和锁有什么关系？
 * 2.事务执行过程中，线程被kill，会导致什么问题（比如数据库有锁释放不了），如何处理？
 * 3.
 * 四大特性（ACID）：
 *      原子性（）：最小操作
 *      一致性：事务完成后（成功或失败），业务出于一致性状态，而非部分完成、部分失败
 *      隔离性：多个事务间并发处理时，数据应该隔离开，防止数据损坏
 *      持久性：事务完成后，无论发生什么系统错误，它的结果都不应该受到影响，这样有利于从任何系统崩溃中恢复。通常情况下，事务的结果会被写入持久化存储器中
 * 事务属性：
 *      传播行为：控制事务嵌套时如何处理，必须"在/不在"事务内执行
 *      隔离规则：控制事务并发时如何处理
 *      回滚规则：通常在运行期抛出异常时做回滚
 *      事务超时：开启事务会对DB数据枷锁，占用资源。如果在事务规定时间内未完成则自动执行回滚操作
 *      是否只读：只读属性用于DB做一些优化措施
 * spring中使用事务：
 *      编程式事务(基于xml，需手动编码，事务范围：代码块级别) VS 声明式事务（基于注解，无需手动编码，事务范围：方法级别）
 *      事务接口：
 *          org.springframework.transaction.TransactionDefinition：事务基本属性定义
 *          org.springframework.transaction.PlatformTransactionManager：事务管理，获取事务、提交、回滚
 *          org.springframework.transaction。TransactionStatus：事务状态
 *      事务管理器：
 *          JDBC事务：
 *          Hibernate事务：
 *          JPA事务：
 *          JTA事务（Java native，distributed transaction）：
 *
 *
 *
 */
public class App {
    public static final String DRIVER = "com.mysql.jdbc.Driver";
    public static final String URL = "jdbc:mysql://localhost:3306/local_chefu?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;zeroDateTimeBehavior=convertToNull&amp;tinyInt1isBit=false&amp;allowMultiQueries=true";
    public static final String USER_NAME = "root";
    public static final String PASS_WORD = "root123";

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        transactionTest();
    }

    private static void transactionTest() throws ClassNotFoundException, SQLException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            conn = getConnection();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            destoryConn(conn,ps,rs);
        }
    }

    /**
     * 获取DB连接
     */
    private static Connection getConnection() throws ClassNotFoundException, SQLException {
        Class.forName(DRIVER);
        Connection connection = DriverManager.getConnection(URL, USER_NAME, PASS_WORD);
        return connection;
    }

    /**
     * 释放DB连接
     */
    private static void destoryConn(Connection connection, PreparedStatement preparedStatement, ResultSet rs) throws SQLException {
        if(rs != null){
            rs.close();
        }
        if(preparedStatement != null){
            preparedStatement.close();
        }
        if(connection != null){
            connection.close();
        }
    }
}
